package com.example.pipeline.config;

import com.common.pattern.pipeline.bo.PipelineContext;
import com.common.pattern.pipeline.config.PipelineRouteConfig;
import com.common.pattern.pipeline.handler.ContextHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;


/**
 * @Author: xuxiang
 * @Date: 2023-8-10
 * @Description: 管道每一节管子的路由顺序配置
 */
@Slf4j
@Configuration
@ConditionalOnClass(ContextHandler.class)
public class MyPipelineRouteConfig extends PipelineRouteConfig implements ApplicationRunner {

    private static final String SPLIT_LINE = "============================================================";

    private static boolean isInit = true;

    @Resource
    private ApplicationContext applicationContext;

    @Override
    @SuppressWarnings("all")
    public void run(ApplicationArguments args) throws Exception {
        synchronized (MyPipelineRouteConfig.class) {
            if (!isInit) {
                isInit = true;

                Map<Class<? extends PipelineContext>,
                        List<ContextHandler<? extends PipelineContext>>> handlerBean
                        = applicationContext.getBean("pipelineRouteMap", Map.class);

                if (CollectionUtils.isEmpty(handlerBean)) {
                    return;
                }

                log.info("正在执行管道自定义加载顺序!");
                handlerBean.forEach((key, handlerList) -> handlerBean.put(key, this.sort(handlerList)));
            }
        }
    }

    /**
     * 模拟动态排序,可以查询数据库,spring动态config皆可
     */
    private List<ContextHandler<? extends PipelineContext>> sort(
            List<ContextHandler<? extends PipelineContext>> handlerList
    ) {

        if (CollectionUtils.isEmpty(handlerList)) {
            return handlerList;
        }

        log.info(SPLIT_LINE);
        log.info("原始管道默认执行顺序为:");
        handlerList.stream().map(handler -> handler.getClass().getSimpleName()).forEach(log::info);
        log.info(SPLIT_LINE);

        List<ContextHandler<? extends PipelineContext>> sortedList =
                new ArrayList<>(handlerList.size());

        sortedList.addAll(handlerList);

        // 模拟新的排序顺序
        Collections.shuffle(sortedList);

        log.info(SPLIT_LINE);
        log.info("管道建立成功,重新排序顺序为:");
        sortedList.stream().map(handler -> handler.getClass().getSimpleName()).forEach(log::info);
        log.info(SPLIT_LINE);
        return sortedList;
    }
}